package cn.com.sina.rd.dsp.servlet;

import cn.com.sina.rd.dsp.balancer.ShipLoad;
import cn.com.sina.rd.dsp.model.Cluster;
import cn.com.sina.rd.dsp.tools.MoveOnce;
import cn.com.sina.rd.dsp.tools.ShowArray;
import cn.com.sina.rd.dsp.tools.ShowMove;
import cn.com.sina.rd.dsp.tools.Utils;
import com.google.common.collect.Maps;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.ConcurrentMap;

import static cn.com.sina.rd.dsp.balancer.doBalance.*;

//import com.alibaba.fastjson.JSONArray;
//import com.alibaba.fastjson.JSONObject;


/**
 * Created with IntelliJ IDEA.
 * User: xinrong3
 * Date: 14-1-13
 * Time: 上午10:03
 */
public class ShowServlet extends HttpServlet {
    public static ConcurrentMap<String,ShowMove> map= Maps.newConcurrentMap();
    public static ConcurrentMap<String,JSONObject> adviseMap= Maps.newConcurrentMap();

    @Override
    protected synchronized void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doGet(req,resp);

    }


    /**
     * result should be json like {}
     * @param req reques
     * @param resp response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/json; charset=utf-8");
        PrintWriter out = resp.getWriter();

        String option=req.getParameter("option");
        String key=req.getParameter("key");
        String source=req.getParameter("source");


        if(option.equals("set")&&Utils.NotNullOrEmpty(source)){
            setMap(key,source);
            JSONObject result=new JSONObject();
            result.put("RST","true");
            result.put("CMD",getAdvice(key).toString());
            out.println(result);
        }else{
            if(option.equals("get")&&Utils.NotNullOrEmpty(key)){
                JSONObject result=new JSONObject();
                JSONObject cluster_state= getCurrent(key);

                if(cluster_state==null||cluster_state.isEmpty()){
                    JSONObject advise  =getAdvice(key);
                    System.out.println("=================================\n"+advise);
                    JSONArray array=advise.getJSONObject(Action.Balance.toString()).getJSONArray(ShipLoad.MOVE_ARRAY);
                    String cmd=getMoveCmd(array);
                    result.put("RST",cmd);

                    result.put("HIGHGATE",advise.getString(Cluster.HIGH_GATE));
                    result.put("LOWGATE",advise.getString(Cluster.LOW_GATE));
                    result.put("AVERAGE",advise.getString(AVERAGE));
                    result.put("ADIVISE",advise.getString(ACTION));
                    clearMap(key);
                }else{
                    MoveOnce mv= getMove(key);

                    ShowArray showArray=new ShowArray(cluster_state);
                    JSONArray names=showArray.getServerArray();
                    JSONArray valus=showArray.getValueArray();

                    if(names.isEmpty()||valus.isEmpty()){
                        result.put("RST","exception");
                    }else{
                        JSONObject advise  =getAdvice(key);
                        result.put("MV",mv.getFrom().getServerName()+"---"+mv.getName().getName()+"--->"+mv.getTo().getServerName());

                        result.put("HIGHGATE",advise.getString(Cluster.HIGH_GATE));
                        result.put("LOWGATE",advise.getString(Cluster.LOW_GATE));
                        result.put("AVERAGE",advise.getString(AVERAGE));
                        result.put("ADIVISE",advise.getString(ACTION));

                        result.put("NAMES",names);
                        result.put("VALUES",valus);

                        result.put("RST","true");

                        System.out.println("--------------------------------------\n"+result);
                    }
                }
                out.println(result);
            }
        }
    }

    private String getMoveCmd(JSONArray array) {
        String cmd="";
        for(int i=0;i<array.size();i++){
            JSONObject o=array.getJSONObject(i);
            cmd+=o.getString("from")+"---"+o.getString("load_name")+"--->"+o.getString("to")+"\n ";
        }
        return "资源迁移序列如下\n"+cmd.trim();
    }

    private void clearMap(String key) {
        map.remove(key);
        adviseMap.remove(key);
    }

    private JSONObject getAdvice(String key) {
        if(adviseMap.containsKey(key)){
            return adviseMap.get(key);
        }else{
            return new JSONObject();
        }
    }

    private JSONObject getCurrent(String key){
        if(map.containsKey(key)){
            ShowMove show= map.get(key);
            if(show.hasNext()){
                JSONObject current=show.next();
                return current;
            }else{
                return new JSONObject();
            }
        }else{
            return new JSONObject();
//
//            ShowMove showMove=new ShowMove(Utils.getJson());
//            map.put(key,showMove);
//            return getCurrent(key);
        }
    }

    private MoveOnce getMove(String key) {
        if(map.containsKey(key)){
            ShowMove show= map.get(key);
            return show.getMv();
        }
        return null;
    }

    private static void setMap(String key,String source){
        if(!map.containsKey(key)){
            ShowMove showMove=new ShowMove(Utils.getJson(source));
            map.put(key,showMove);
            adviseMap.put(key,showMove.getResult());
        }
    }
}
